//
//  LDPressButton.swift
//  DaFit
//
//  Created by sylar on 2018/6/23.
//  Copyright © 2018年 sylar. All rights reserved.
//

import Foundation
import UIKit

public enum LDProgressButtonStyle {

    case White
    case Gray
    case Black
}

public enum LDProgressButtonState {
    case Begin
    case Moving
    case WillCancel
    case DidCancel
    case End
    case Click
}

public typealias actionState = (_ state: LDProgressButtonState) -> Void

open class LDPressButton: UIButton {

    /// 计时时长
    public var interval: Float = 1.5

    /// 进度条颜色
    open var progressColor: UIColor! {
        didSet {
            self.progressLayer.strokeColor = progressColor.cgColor
        }
    }

    private var buttonAction: actionState?

    private lazy var progressLayer: CAShapeLayer = {
        let layer = CAShapeLayer()
        layer.fillColor = UIColor.clear.cgColor
        layer.strokeColor = UIColor.Training.theme.cgColor
        layer.lineWidth = 4
        layer.lineCap = CAShapeLayerLineCap.round
        return layer
    }()

//    @available(iOS 10.0, *)
    private lazy var link: CADisplayLink = {
        let link = CADisplayLink.init(target: self, selector: #selector(linkRun))
//        link.preferredFramesPerSecond = 60
        link.add(to: RunLoop.current, forMode: RunLoop.Mode.default)
        link.isPaused = true
        return link
    }()

    private var tempInterval: Float = 0.0
    private var progress: Float = 0.0
    private var isTimeOut: Bool = false
    private var isPressed: Bool = false
    private var isCancel: Bool = false
    private var ringFrame: CGRect = .zero

    deinit {
        print("deinit LZPressButton")
        self.link.invalidate()
    }

    public override init(frame: CGRect) {
        super.init(frame: frame)

        self.backgroundColor = UIColor.clear
        let longPress = UILongPressGestureRecognizer.init(target: self, action: #selector(longPressGesture))
        self.addGestureRecognizer(longPress)

        let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapGesture))
        self.addGestureRecognizer(tap)
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let longPress = UILongPressGestureRecognizer.init(target: self, action: #selector(longPressGesture))
        self.addGestureRecognizer(longPress)

        let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapGesture))
        self.addGestureRecognizer(tap)
//        fatalError("init(coder:) has not been implemented")
    }

    open func actionWithClosure(_ closure: @escaping actionState) {

        self.buttonAction = closure
    }

    @objc private func tapGesture() {

        if let closure = self.buttonAction {
            closure(.Click)
        }
    }

    @objc private func longPressGesture(_ gesture: UILongPressGestureRecognizer) {

        switch gesture.state {
        case .began:

            self.link.isPaused = false
            self.isPressed = true
            self.layer.addSublayer(self.progressLayer)
            if let closure = self.buttonAction {
                closure(.Begin)
            }
        case .changed:
            let point = gesture.location(in: self)
            if self.ringFrame.contains(point) {
                self.isCancel = false
                if let closure = self.buttonAction {
                    closure(.Moving)
                }
            } else {
                self.isCancel = true
                if let closure = self.buttonAction {
                    closure(.WillCancel)
                }
            }
        case .ended:
//            log.debug("longPressGesture end")
            self.stop()
            if self.isCancel {
                if let closure = self.buttonAction {
                    closure(.DidCancel)
                }
            }
//            } else if self.isTimeOut == false {
//                if let closure = self.buttonAction {
//                    closure(.End)
//                }
//            }

            self.isTimeOut = false
        default:
            self.stop()
            self.isCancel = true
            if let closure = self.buttonAction {
                closure(.DidCancel)
            }
        }

        self.setNeedsDisplay()
    }

    @objc private func linkRun() {
        tempInterval += 1 / 60.0
        progress = tempInterval / interval
        self.setNeedsDisplay()
    }

    open func stop() {

        isPressed = false
        tempInterval = 0.0
        progress = 0.0

        self.progressLayer.strokeEnd = 0
        self.progressLayer.removeFromSuperlayer()
        self.link.isPaused = true
        self.setNeedsDisplay()

    }
    open override func draw(_ rect: CGRect) {

        let width = self.bounds.width
        let mainWidth = width
        let mainFrame = CGRect(x: 1, y: 1, width: mainWidth-2, height: mainWidth-2)

        if self.isPressed {

            let progressFrame = mainFrame.insetBy(dx: 0, dy: 0)
            let progressPath = UIBezierPath.init(roundedRect: progressFrame, cornerRadius: progressFrame.width)
            self.progressLayer.path = progressPath.cgPath
            if self.progress >= 1 {
                self.progress = 1
            }
            self.progressLayer.strokeEnd = CGFloat(self.progress)
//            log.debug("progress =\(self.progress)")
            if self.progress == 1 {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.4, execute: { [weak self] in

                        self?.stop()
                        self?.isTimeOut = true
                        if let closure = self?.buttonAction {
                            closure(.End)
                        }
                    })
            }
        }
    }
}
